package com.joint.web.action.com;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fz.us.base.bean.Pager;
import com.fz.us.base.util.DataUtil;
import com.google.common.collect.Maps;
import com.joint.web.action.BaseFlowAction;
import net.sf.json.JSONObject;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.repository.Model;
import org.apache.struts2.ServletActionContext;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by hpj on 2015/1/28.
 */
@ParentPackage("com")
public class AjaxModelerAction extends BaseFlowAction {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    private String name;
    private String description;
    private String key;
    private String modelerId;

    public String list(){
        pager = new Pager(0);
        /*
        pager.setPageSize(rows);
        pager.setPageNumber(page);
        */
        List<JSONObject> dataRows=new ArrayList<JSONObject>();
        Map<String,Object> data=new HashMap<String, Object>();
        Map<String, Object> rMap = null;

        int first = (page-1)*rows;
        int end = page*rows;
        List<Model> allList = repositoryService.createModelQuery().orderByCreateTime().desc().list();
        List<Model> modelList = allList;
        /*
        if (allList!= null && allList.size()>0){
            if (end > allList.size()){
                end = allList.size();
            }
            modelList = allList.subList(first,end);
        }else {
            modelList = new ArrayList<>();
        }*/


        for(Model model : modelList){
            rMap = Maps.newHashMap();
            rMap.put("id",model.getId());
            rMap.put("name",model.getName());
            rMap.put("key",model.getKey());
            rMap.put("time", DataUtil.friendly_time(model.getCreateTime()));
            dataRows.add(JSONObject.fromObject(rMap));
        }
        long total =allList.size();
        if(total%rows==0){
            total = total/rows;
        }else{
            if(total<rows){
                total = 1;
            }else{
                total = total/rows + 1;
            }
        }
        data.put("dataRows",dataRows);
        data.put("page",page);
        data.put("rows",rows);
        data.put("total",total);
        data.put("records",dataRows.size());
        return  ajaxJson(JSONObject.fromObject(data).toString());
    }
    public String save(){
        try{
            ObjectMapper objectMapper = new ObjectMapper();
            ObjectNode editorNode = objectMapper.createObjectNode();
            editorNode.put("id", "canvas");
            editorNode.put("resourceId", "canvas");
            ObjectNode stencilSetNode = objectMapper.createObjectNode();
            stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
            editorNode.put("stencilset", stencilSetNode);

            HttpServletResponse response = ServletActionContext.getResponse();
            HttpServletRequest request = ServletActionContext.getRequest();
            Model modelData = repositoryService.newModel();

            ObjectNode modelObjectNode = objectMapper.createObjectNode();
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            modelData.setMetaInfo(modelObjectNode.toString());
            modelData.setName(name);
            modelData.setKey(key);
            repositoryService.saveModel(modelData);
            repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));

            Map<String,Object> oMap = Maps.newHashMap();
            oMap.put("modelerId", modelData.getId());
            return ajaxHtmlAppResult(200, "正在跳转！", JSONObject.fromObject(oMap));
        }catch(Exception e){
            logger.error("创建模型失败：", e);
            return ajaxHtmlCallback("400", "创建模型失败！","操作状态");
        }
    }
    public String deploy(){
        try {
            Model modelData = repositoryService.getModel(modelerId);

            ObjectNode modelNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
            byte[] bpmnBytes = null;

            BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode);
            bpmnBytes = new BpmnXMLConverter().convertToXML(model);

            String processName = modelData.getName() + ".bpmn20.xml";
            DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().addString(processName,new String(bpmnBytes, "UTF-8"));
            deploymentBuilder.name(modelData.getName());
            Deployment deployment = deploymentBuilder.deploy();
            return ajaxHtmlCallback("200", deployment.getName()+"部署成功，请查看！","操作状态");
        } catch (IOException e) {
            return ajaxHtmlCallback("400", "部署失败，请联系管理员！","操作状态");
        }

    }
    public String delete(){
        repositoryService.deleteModel(modelerId);
        return ajaxHtmlCallback("200", "删除成功，请查看！","操作状态");
    }



    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getModelerId() {
        return modelerId;
    }

    public void setModelerId(String modelerId) {
        this.modelerId = modelerId;
    }
}
